#ifndef GEN_READER_H
#define GEN_READER_H

#include "reader.h"
#include <vector>
#include <map>
#include <sstream>

#define NUM_GEN_SIZE sizeof(int)
#define	GEN_ID_SIZE	(sizeof(char) * 2)
#define GEN_NAME_SIZE (sizeof(char) * 20)
#define GEN_BUS_ID_SIZE sizeof(long)
#define GEN_INFO_HEADER_SIZE (GEN_ID_SIZE+GEN_NAME_SIZE+GEN_BUS_ID_SIZE)

#define NUM_GEN_OFFSET 6 * sizeof(int)
#define GEN_INFO_HEADER_OFFSET (NUM_GEN_OFFSET + NUM_GEN_SIZE)
#define MAX_GEN_VAR 26

#define NUM_SUMMARY_DATA 12

#define GET_GEN_VAR_SQL  "SELECT VALUE FROM SIMULATIONCONTROL WHERE NAME='Hour Var Selection Generator'"

#define GET_GEN_ANC_INDEX_SQL "SELECT VALUE FROM SIMULATIONCONTROL WHERE NAME='Ancillary Service Type Index'"

#define GET_GEN_EMISSION_COUNT_SQL "SELECT COUNT(MONITOR)AS NUM_EMI FROM EMISSIONTYPE WHERE MONITOR=-1"

#define GET_GEN_EMISSION_NAME_SQL "SELECT NAME FROM EMISSIONTYPE WHERE MONITOR=-1"

#define GET_GEN_ANC_SETTING_SQL "SELECT VALUE FROM SIMULATIONCONTROL WHERE NAME='Hour Var Selection Generator'"//???

#define GET_GEN_EMISSION_SETTING_SQL "SELECT VALUE FROM SIMULATIONCONTROL WHERE NAME='Emission Model Option'"

#define GET_GEN_AREA_SEL_SQL "SELECT DISTINCT LoadAreaName FROM loadarea WHERE  EXISTS(SELECT g.loadareaid FROM generator g  WHERE ( g.RetirementDate>=(SELECT value FROM simulationcontrol WHERE name='Simulation Start Date') AND g.commissiondate<=(SELECT value FROM simulationcontrol WHERE name='Simulation End Date' )AND g.servicestatus=true AND g.savetobinary=-1  ))"

#define GET_GEN_AREA_ALL_SQL "SELECT DISTINCT LoadAreaName FROM loadarea WHERE  EXISTS(SELECT g.loadareaid FROM generator g  WHERE ( g.RetirementDate>=(SELECT value FROM simulationcontrol WHERE name='Simulation Start Date') AND g.commissiondate<=(SELECT value FROM simulationcontrol WHERE name='Simulation End Date' )AND g.servicestatus=true ))"

#define GET_GEN_TYPES	"SELECT DISTINCT GENERATORTYPE AS TYPE FROM GENERATOR"

#define GET_GEN_SUBTYPES	"SELECT DISTINCT SUBTYPE FROM GENERATOR" // Yanli Wei, 06/04/2010

#define GET_GEN_FULL_INFO "SELECT g.generatorname,g.generatortype, g.subtype, g.commissiondate, g.retirementdate,f.fuelname, l.loadareaname, r.regionname  from loadarea l, region r, generator g, fuel f  where g.loadareaid=l.loadareaid and r.regionid = l.regionid and  f.fuelid=g.fuelid"


typedef struct _gen_info 
{
	char gen_name[20];
	long bus_id;
	char gen_id[2];
}gen_info;

typedef struct _gen_full_info 
{
	CString gen_name;
	CString gen_type;
	CString gen_subtype; // Subtype added by Yanli Wei, 06/04/2010
	CString install_date;
	CString retire_date;
	CString fuel_name;
	CString area_name;
	CString region_name;
}gen_full_info;

typedef struct _gen_yearly_data
{
	float STAT_avg_LMP;
	float STAT_avg_LMP_Cong;
	float STAT_avg_LMP_Loss;
	float STAT_Total_Generation;
	float STAT_Total_ProductionCost_M;
	float STAT_Total_Revenue_M;
	float STAT_Total_NetRevenue_M;
	float STAT_Total_Maint;
	float STAT_Total_Commitment;
	float STAT_Total_ForcedOutage;
	float STAT_Total_Marginal;
	float STAT_Avg_DispFLAC;
}gen_yearly_data;


typedef struct _stats
{
	float total;
	float avg;
	float min;
	float max;
}stats;

class gen_reader: public reader
{

protected:

	int summary_file_Handle;					// file handlder for summary binary file
	long hourly_num_gen;						// total number of generator store in the hourly binary file
	CString gen_var_setting;					// generator variable output bit setting
	CString gen_anc_setting;					// generator Ancillary Service setting
	CString gen_emssions_count;					// generator emssions Count setting
	CString gen_emssions_option;				// generator option setting

	map <CString, int> hourly_gen_index_map;	// hourly generators' name and index map
	map <CString, int> var_index_map;			// hourly generator varables name and index map

	/* read generator varables setting from MS DB*/
	void read_gen_var_setting(CString * gen_var_setting);
	/* read generator info from binary file (hourly, summary)*/
	void read_gen_info(int f_handler, long * num, vector<gen_info> * info_list, map <CString, int> * info_map);
	/* read number of generator from binary file (hourly, summary)*/
	void read_gen_num(int f_handle, long * num);
	/* setup generator types and index map */
	void setGenTypeMap();
	void readGenSubtype(); // Yanli Wei, 06/04/2010
	void readEmissionType(); // Yanli Wei, 06/09/2010


public:

	int num_ancs;								// Total number of Ancillary Service
	int num_vars;								// Total number of selected output generator variables
	int num_emissions;							// Total number of emissions
    int emissions_option;                       // Emission option, Yanli Wei, 06/09/2010
	vector<char *> gen_var_list;				// Generator variables list
	vector<gen_info> hourly_gen_info_list;		// Generator information list 
	vector<CString> gen_type_list;				// Generator types list
	vector<CString> gen_subtype_list;           // Generator subtypes list, Yanli Wei, 06/04/2010
	vector<CString> emission_type_list;         // Emission type list, Yanli Wei, 06/09/2010     
	vector<CString> AS_type_list;				// Ancillary service type list, Yanli Wei, 06/10/2010
	map <CString, int> gen_type_map;			// generator types and index map

	/* constructors and deconstructor */
	gen_reader();
	gen_reader(char *HourlyBinFile, char *SummaryBinFile, char *dbFile);
	~gen_reader();

	char ** get_gen_var_list();
	int get_var_list_size();
	int get_gen_info_list_size();
	int get_gen_var_list_size();
	int get_gen_index(char *, map <CString, int> * );
	long get_num_gen();


	unsigned long get_hourly_var_offset(int gen_index, unsigned long hour, int var_index);
	unsigned long get_summary_data_offset(int gen_index);

	float get_gen_var(char *gen_name, char *var_name, int hour);
	float * getAllHourlyVal(char* gen_name, unsigned long gen_hrs);
	float getCommitCode(char* gen_name, int hour);

	vector<CString> get_gen_area_list();
	vector<CString>  get_gen_list_byTypeAndArea(CString type, CString Area);
	vector<gen_full_info> get_gen_full_info_all();

	gen_info * get_gen_info_list();
	gen_yearly_data get_gen_yearly_data(CString gen_name);
	gen_full_info get_gen_full_info(CString gen_name);

	void readAncSetting(CString);
	void readEmssionsOption(CString gen_emssions_option); // Yanli Wei, 06/09/2010
	void readEmssionsCount(CString gen_emssions_count); // Yanli Wei, 06/09/2010

};

#endif